/*  Copyright (C) 2012 Vladimir M. <mlvl.jr@gmail.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; by version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

import QtQuick 2.0

Canvas {
    id: hand

    //0..59
    property int tick

    property real tailRatio: 0.2
    property real marginRatio: 0.4

    property real widthToRadiusRatio: 0.4
    property real topCapHeightToRadiusRatio: 0.05
    property real bottomCapHeightToRadiusRatio: 0.05

    property color color: "red"
    property real outlineDarkerFactor: 1.2
    property real outlineLineWidth: 0.3

    antialiasing: true

    onPaint: {
        //this mere string crashes the app on a resize to full-screen with NVidia drivers
        //on Linux with G105M card
        //var ctx = getContext('2d')

        var ctx = getContext('2d')

        ctx.clearRect(0, 0, width, height)
        ctx.save()

        var radius = width/2.0

        ctx.translate(width/2.0, height/2.0)
        ctx.rotate(tick/60.0*Math.PI*2)
        ctx.scale(1.0, -1.0)

        var handWidth = widthToRadiusRatio*radius
        var topCapHeight = topCapHeightToRadiusRatio*radius
        var bottomCapHeight = bottomCapHeightToRadiusRatio*radius

        ctx.fillStyle = color
        ctx.strokeStyle = Qt.darker(color, outlineDarkerFactor)
        ctx.lineWidth = outlineLineWidth

        var halfWidth = handWidth/2.0
        var tailHeight = tailRatio*radius
        var mainHeight = (1.0 - marginRatio)*radius
        var topCapRadius = capRadius(handWidth, topCapHeight)
        var bottomCapRadius = capRadius(handWidth, bottomCapHeight)

        ctx.beginPath()

        simpleArc(ctx, handWidth, topCapRadius, mainHeight, true)
        simpleArc(ctx, handWidth, bottomCapRadius, -tailHeight, true)

        ctx.closePath()

        ctx.fill()
        ctx.stroke()

        ctx.restore()
    }

    onTickChanged: requestPaint()

    function simpleArc(ctx, width, radius, yTop, counterClockwise) {
        var phi = Math.asin(width/2.0/radius)
        var swap = counterClockwise?1:(-1)

        if (yTop > 0) {
            ctx.arc(0, yTop - radius,
                    radius,
                    Math.PI/2 + swap*phi, Math.PI/2 - swap*phi,
                    counterClockwise)
        } else {
            ctx.arc(0, yTop + radius,
                    radius,
                    -Math.PI/2 + swap*phi, -Math.PI/2 - swap*phi,
                    counterClockwise)
        }
    }

    function capRadius(width, dy) {
        var numericThreshhold = 0.5
        var defaultRadius = 1000

        if (dy < numericThreshhold)
            return defaultRadius

        var dx = width/2.0

        return (dy*dy  + dx*dx)/(2*dy)
    }
}
